using System;
using System.Collections.Generic;
using Headspring.Training.Core.Model;
using Headspring.Training.Core.Services.Impl;
using NHibernate;
using NUnit.Framework;

namespace Headspring.Training.IntegrationTests
{
	[TestFixture]
	public class ZDataLoader : DataTestBase
	{
		private static Employee createNewEmployee(string username, string firstName,
		                                          string lastName, string email,
		                                          string password)
		{
			var employee = new Employee(username, firstName, lastName, email);
			SetPassword(employee, password);
			return employee;
		}

		private static void SetPassword(Employee employee, string password)
		{
			var cryptographyService = new CryptographyService();
			employee.PasswordSalt = cryptographyService.CreateSalt();
			employee.PasswordHash = cryptographyService.HashPassword(password,
			                                                         employee.
			                                                         	PasswordSalt);
		}

		[Test, Category("DataLoader")]
		public void PopulateDatabase()
		{
			ISession session = getSession();
			ITransaction transaction = session.BeginTransaction();
			TestHelper.ClearTables();


			Employee homer = createNewEmployee("hsimpson", "Homer", "Simpson",
			                                   "homer@simpsons.com", "beer");
			Employee marge = createNewEmployee("msimpson", "Marge", "Simpson",
			                                   "marge@simpsons.com", "beer");
			Employee bart = createNewEmployee("bsimpson", "Bart", "Simpson",
			                                  "bart@simpsons.com", "beer");
			Employee lisa = createNewEmployee("lsimpson", "Lisa", "Simpson",
			                                  "lisa@simpsons.com", "beer");

			session.SaveOrUpdate(homer);
			session.SaveOrUpdate(marge);
			session.SaveOrUpdate(bart);
			session.SaveOrUpdate(lisa);

			//put in test employee/manager/secretary data
			var secretary = new Secretary("somesecretary1", "Some", "Secretary",
			                              "Somesecretary@bigwig.com");
			SetPassword(secretary, "beer");

			var everyonesManager = new Manager("ManagerOfEveryone", "Bob", "Bigwig",
			                                   "bob@bigwig.com", null);
			SetPassword(everyonesManager, "beer");

			session.SaveOrUpdate(secretary);
			session.SaveOrUpdate(everyonesManager);


			//Trainer below
			Employee jpalermo = createNewEmployee("jpalermo", "Jeffrey", "Palermo",
			                                      "jpalermo@headspringsystems.com",
			                                      "beer");

			jpalermo.Manager = everyonesManager;

			session.SaveOrUpdate(jpalermo);

			//Student 1 below
			Employee lee = createNewEmployee("lee", "Lee", "Brandt",
			                                 "leebrandt@gmail.com", "beer");
			lee.Manager = everyonesManager;
			session.SaveOrUpdate(lee);


			//Student 2 below
			Employee tae = createNewEmployee("tae", "Tae-Sung", "Shin",
			                                 "Shin_Tae-Sung@cat.com", "beer");
			tae.Manager = everyonesManager;

			session.SaveOrUpdate(tae);


			//Student 3 below
			Employee hwei = createNewEmployee("hwei", "hua", "wei",
			                                  "hua.wei@tea.tx.state.us",
			                                  "beer");
			hwei.Manager = everyonesManager;
			session.SaveOrUpdate(hwei);

			//Student 4 below
			Employee lveal = createNewEmployee("lveal", "Linda", "Veal",
			                                   "lveal@tea.tx.state.us",
			                                   "beer");

			lveal.Manager = everyonesManager;
			session.SaveOrUpdate(lveal);


			//Student 5 below
			Employee jack = createNewEmployee("jroman", "Jack", "Roman",
			                                  "jroman2302@yahoo.com",
			                                  "beer");

			jack.Manager = everyonesManager;
			session.SaveOrUpdate(jack);

			//Student 6 below
			Employee craig = createNewEmployee("craig", "craig", "bowes",
			                                   "craig@bowesfamily.com",
			                                   "beer");

			craig.Manager = everyonesManager;
			session.SaveOrUpdate(craig);


			//Student 7 below
			Employee phil = createNewEmployee("phil", "Phil", "Jensen",
			                                  "phil.jensen@callawaygolf.com",
			                                  "beer");

			phil.Manager = everyonesManager;
			session.SaveOrUpdate(phil);


			session.Flush();
			IList<Employee> allEmployees =
				session.CreateCriteria(typeof (Employee)).List<Employee>();
			foreach (Employee creator in allEmployees)
			{
				foreach (Employee assignee in allEmployees)
				{
					var order = new WorkOrder
					            	{
					            		Number = Guid.NewGuid().ToString().Substring(0, 5).ToUpper(),
					            		Creator = creator,
					            		Assignee = assignee,
					            		CreatedDate = DateTime.Now,
					            		Status = WorkOrderStatus.Draft,
					            		Title = "Work Order",
					            		Description = "Foo, foo, foo, foo"
					            	};
					order.ChangeStatus(WorkOrderStatus.Draft, creator, DateTime.Now);
					order.ChangeStatus(WorkOrderStatus.Assigned, creator, DateTime.Now);
					order.ChangeStatus(WorkOrderStatus.InProgress, assignee, DateTime.Now);
					order.ChangeStatus(WorkOrderStatus.Complete, assignee, DateTime.Now);
					order.ChangeStatus(WorkOrderStatus.Cancelled, creator, DateTime.Now);

					session.SaveOrUpdate(order);

					foreach (WorkOrderStatus status in WorkOrderStatus.GetAllItems())
					{
						var order2 = new WorkOrder
						             	{
						             		Number =
						             			Guid.NewGuid().ToString().Substring(0, 5).ToUpper(),
						             		Creator = creator,
						             		Assignee = assignee,
						             		CreatedDate = DateTime.Now,
						             		Status = status,
						             		Title = ("Work Order in status " + status),
						             		Description = ("Foo, foo, foo, foo " + status)
						             	};

						session.SaveOrUpdate(order2);
					}
				}
			}


			transaction.Commit();
			session.Dispose();
		}
	}
}